/*
 * soap_create.c
 * 
 * Copyright 2013 Raju <raju39k@gmail.com>
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 * 
 * 
 */

/**
 * @file soap_create.c
 * @author Reddeiah Raju Konduru (raju39k@gmail.com)
 * @date   July, 2013
 * @brief  This is the main function of cpe program.
 * This is the program for handling all other cpe operations.
 */
 
/******************************************************************************
 *                              HEADER FILE INCLUSIONS                        *
 ******************************************************************************/
 #include "soap_create.h"


/******************************************************************************
 *                                 MACRO DEFINITIONS                          *
 ******************************************************************************/
/** SOAP Envelope Schema URL */
 #define SOAP_ENVELOPE_URL    "http://schemas.xmlsoap.org/soap/envelope/"
 #define SOAP_ENCODING_URL    "http://schemas.xmlsoap.org/soap/encoding/"
 #define XML_XSI_URL          "http://www.w3.org/2001/XMLSchema/instance/"
 #define XML_XSD_URL          "http://www.w3.org/2001/XMLSchema/"
 #define CWMP_DATAMODEL       "urn:dslforum-org:cwmp-1-0"
 #define CWMP_SCHEMA          "xmlns:cwmp=urn:dslforum-org:cwmp-1-0"
 #define XSI_TYPE             "xsi:type"

/******************************************************************************
 *                                 GLOBAL VARIABLES                           *
 ******************************************************************************/
 
 
/******************************************************************************
 *                           STATIC FUNCTION PROTOTYPES                       *
 ******************************************************************************/


/******************************************************************************
 *                               FUNCTION DEFINITIONS                         *
 ******************************************************************************/

/**
 * @brief This function will create Inform RPC Message
 * Description:
 * 
 *         a. Check for lemons
 * 
 *         b. Create IXML Doccument and Elements with Details
 * 
 *         c. Return the created Inform Message
 * 
 * @param[in] sh A pointer Soap Header Structure
 * @param[in] deviceId A deviceId Structure contains Device Details
 * @param[in] events A ponter to list of Events caused the inform
 * @param[in] maxEnvelope Number of Maximum Envelopes supported
 * @param[in] currentTime Current Date and Time Structure
 * @param[in] retryCount Number of Retries done upto now
 * @param[in] parameterList A pointer to List of Parameters
 * 
 * @return IXML_Doccument if inform created successfully otherwise NULL
 */
/******************************************************************************
 *                                                                            *
 *                        INFORM MESSAGE CREATION                             *
 *                                                                            *
 ******************************************************************************/
 IXML_Document *createInform(SoapHeader_t *sh, 
                             DeviceIdStruct_t deviceId, 
                             EventList_t *events, 
                             unsigned int maxEnvelope, 
                             DateTime_t currentTime, 
                             unsigned int retryCount, 
                             ParameterValueList_t *parameterList)
{
	PRINT_FUNC_TRACE(ENTERED)

	IXML_Element  *parameter_list = NULL;
	IXML_Element  *max_envelopes = NULL;
	IXML_Element  *event_struct = NULL;
	IXML_Element  *retry_count = NULL;
	IXML_Element  *device_id = NULL;
	IXML_Element  *date_time = NULL;
	IXML_Document *soap_doc = NULL;
	IXML_Element  *envelope = NULL;
	IXML_Element  *inform = NULL;
	IXML_Element  *body = NULL;

	/** Creating SOAP Doccument */
	soap_doc = ixmlDocument_createDocument();

	/** Creating SOAP Envelope */
	envelope = ixmlDocument_createElementNS(soap_doc, SOAP_ENVELOPE_URL, "soap:Envelope");
	ixmlElement_setAttribute(envelope, "xmlns:soap", SOAP_ENVELOPE_URL);
	ixmlElement_setAttribute(envelope, "soap:encodingStyle",SOAP_ENCODING_URL);
	ixmlElement_setAttribute(envelope, "xmlns:xsi", XML_XSI_URL);
	ixmlElement_setAttribute(envelope, "xmlns:xsd", XML_XSD_URL);
	ixmlElement_setAttribute(envelope, "xmlns:cwmp", CWMP_DATAMODEL);

	/** Add SOAP Envelope to SOAP Doccument */
	ixmlNode_appendChild((IXML_Node *)soap_doc, (IXML_Node *)envelope);

	/** Create SOAP Header and append to Envelope */
	if (sh != NULL) {
		IXML_Node *header = createHeader(soap_doc, sh);
		ixmlNode_appendChild((IXML_Node *)envelope, (IXML_Node *)header);
	}

	/** Create SOAP Body and append to Envelope */
	body = ixmlDocument_createElementNS(soap_doc, SOAP_ENVELOPE_URL, "soap:Body");
	ixmlNode_appendChild((IXML_Node *)envelope, (IXML_Node *)body);

	/** Create CWMP Message and append to Envelope */
	inform = ixmlDocument_createElementNS(soap_doc, CWMP_SCHEMA, "cwmp:Inform");
	ixmlNode_appendChild((IXML_Node *)body, (IXML_Node *)inform);

	/** Create Device, Event, MaxEnvelope, Time, Retry Count, Parameter List */
	device_id = createDeviceId(soap_doc, &deviceId);
	event_struct = createEvent(soap_doc, events);
	max_envelopes = createMaxEnvelope(soap_doc, maxEnvelope);
	date_time = createDateTime(soap_doc, &currentTime);
	retry_count = createRetryCount(soap_doc, retryCount);
	parameter_list = createParameterList(soap_doc, parameterList);

	/** Add Device, Event, MaxEnvelope, Time, Retry Count, Parameter List */
	ixmlNode_appendChild((IXML_Node *)inform, (IXML_Node *)device_id);
	ixmlNode_appendChild((IXML_Node *)inform, (IXML_Node *)event_struct);
	ixmlNode_appendChild((IXML_Node *)inform, (IXML_Node *)max_envelopes);
	ixmlNode_appendChild((IXML_Node *)inform, (IXML_Node *)date_time);
	ixmlNode_appendChild((IXML_Node *)inform, (IXML_Node *)retry_count);
	ixmlNode_appendChild((IXML_Node *)inform, (IXML_Node *)parameter_list);

	PRINT_FUNC_TRACE(EXITED)

	return soap_doc;
}


/**
 * @brief This function will Device Id Struct Message
 * Description:
 * 
 *         a. Check for lemons
 * 
 *         b. Create and return Device Id Struct SOAP Message
 * 
 * @param[in] doc A pointer Soap SOAP Message Doccument
 * @param[in] deviceId A pointer to structure of Device Details
 * 
 * @return IXML_Element Created Device Id Struct SOAP Message
 */
/******************************************************************************
 *                                                                            *
 *                    DEVICE ID STRUCT MESSAGE CREATION                       *
 *                                                                            *
 ******************************************************************************/
IXML_Element *createDeviceId(IXML_Document* doc, DeviceIdStruct *deviceId)
{
	/** Create DeviceId Struct SOAP Message */
	IXML_Element *deviceElement = ixmlDocument_createElementNS(doc, CWMP_SCHEMA, "DeviceId");
	ixmlElement_setAttribute(deviceElement, XSI_TEXT, "cwmp:DeviceIdStruct");

	/** Create Elements for DeviceId Struct parameters */
	IXML_Element *manufacturer = ixmlDocument_createElementNS(doc, CWMP_SCHEMA, "Manufacturer");
	IXML_Element *oui = ixmlDocument_createElementNS(doc, CWMP_SCHEMA, "OUI");
	IXML_Element *prdClass = ixmlDocument_createElementNS(doc, CWMP_SCHEMA, "ProductClass");
	IXML_Element *serialNum = ixmlDocument_createElementNS(doc, CWMP_SCHEMA, "SerialNumber");

	/** Create Node for DeviceId Struct Values */
	IXML_Node* manfText = ixmlDocument_createTextNode(doc, deviceId->manufactorer);
	IXML_Node* ouiText = ixmlDocument_createTextNode(doc, deviceId->OUI);
	IXML_Node* prdClassText = ixmlDocument_createTextNode(doc, deviceId->productClass);
	IXML_Node* snText = ixmlDocument_createTextNode(doc, deviceId->serialNumber);

	/** Set Attribute to Elements */
	ixmlElement_setAttribute(manufacturer, XSI_TEXT, "xsd:string[64]" );
	ixmlElement_setAttribute(oui, XSI_TEXT, "xsd:string[6]");
	ixmlElement_setAttribute(prdClass, XSI_TEXT, "xsd:string[64]");
	ixmlElement_setAttribute(serialNum, XSI_TEXT, "xsd:string[64]" );

	/** Add Device Id Struct values to Elements*/
	ixmlNode_appendChild((IXML_Node *)manufacturer, manfText);
	ixmlNode_appendChild((IXML_Node *)oui, ouiText);
	ixmlNode_appendChild((IXML_Node *)prdClass, prdClassText);
	ixmlNode_appendChild((IXML_Node *)serialNum, snText);

	/** Add Elemets to DeviceId Struct SOAP doccument */
	ixmlNode_appendChild( (IXML_Node *)deviceElement, (IXML_Node *)manufacturer );
	ixmlNode_appendChild( (IXML_Node *)deviceElement, (IXML_Node *)oui );
	ixmlNode_appendChild( (IXML_Node *)deviceElement, (IXML_Node *)prdClass );
	ixmlNode_appendChild( (IXML_Node *)deviceElement, (IXML_Node *)serialNum );

	return deviceElement;
}
